import os
import pandas as pd
from PySide6.QtCore import QUrl, Qt
from PySide6.QtGui import QDesktopServices
from PySide6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QApplication, QTableWidget, \
    QPlainTextEdit, QTableWidgetItem, QFileDialog, QLineEdit, QHBoxLayout

from utils.log_recorder import setup_logger as logger


class ExcelPage(QWidget):
    """ExcelPage 类"""

    def __init__(self, log_text_edit):
        super().__init__()
        self.log_text_edit = log_text_edit
        self.initUI()

    def initUI(self):
        """初始化UI"""
        # 设置布局
        layout = QVBoxLayout(self)

        # 创建水平布局来放置第一个文件的路径和选择按钮
        horizontal_layout_1 = QHBoxLayout()
        self.file_path_label_1 = QLabel("未选择文件")
        self.select_button_1 = QPushButton("选择Excel文件")
        horizontal_layout_1.addWidget(self.file_path_label_1)
        horizontal_layout_1.addWidget(self.select_button_1)

        # 创建水平布局来放置第二个文件的路径和选择按钮
        horizontal_layout_2 = QHBoxLayout()
        self.file_path_label_2 = QLabel("未选择文件")
        self.select_button_2 = QPushButton("选择Excel文件")
        horizontal_layout_2.addWidget(self.file_path_label_2)
        horizontal_layout_2.addWidget(self.select_button_2)

        # 添加输入框以让用户输入要比较的列名
        self.column_name_input = QLineEdit()
        self.column_name_input.setPlaceholderText("输入要比较的列名")
        self.compare_button = QPushButton("对比Excel文件")

        # 创建一个水平布局来放置输入框和对比按钮
        horizontal_layout = QHBoxLayout()
        horizontal_layout.addWidget(self.column_name_input)
        horizontal_layout.addWidget(self.compare_button)

        # 创建结果标签和表格
        self.result_label = QLabel("对比结果将显示在这里")
        self.result_label.setOpenExternalLinks(True)  # 允许打开外部链接
        self.result_label.setTextInteractionFlags(Qt.TextBrowserInteraction)  # 设置文本交互标志
        self.result_label.linkActivated.connect(self.open_file_on_link)  # 连接链接点击事件
        self.result_table = QTableWidget()

        # 将水平布局添加到主布局中
        layout.addLayout(horizontal_layout_1)
        layout.addLayout(horizontal_layout_2)
        layout.addLayout(horizontal_layout)
        layout.addWidget(self.result_label)
        layout.addWidget(self.result_table)

        # 连接按钮的点击事件
        self.select_button_1.clicked.connect(self.select_file_1)
        self.select_button_2.clicked.connect(self.select_file_2)
        self.compare_button.clicked.connect(self.compare_excel_files)

        # 初始化文件路径
        self.file_path_1 = None
        self.file_path_2 = None
        self.differences_file_path = None

    def select_file_1(self):
        """选择第一个Excel文件"""
        self.file_path_1, _ = QFileDialog.getOpenFileName(self, "选择第一个Excel文件", "", "Excel Files (*.xlsx *.xls)")
        if self.file_path_1:
            self.file_path_label_1.setText(f"已选择: {self.file_path_1}")
            self.log(f"选择的第一个Excel文件: {self.file_path_1}")
            logger().info(f"选择的第一个Excel文件: {self.file_path_1}")

    def select_file_2(self):
        """选择第二个Excel文件"""
        self.file_path_2, _ = QFileDialog.getOpenFileName(self, "选择第二个Excel文件", "", "Excel Files (*.xlsx *.xls)")
        if self.file_path_2:
            self.file_path_label_2.setText(f"已选择: {self.file_path_2}")
            self.log(f"选择的第二个Excel文件: {self.file_path_2}")
            logger().info(f"选择的第二个Excel文件: {self.file_path_2}")

    def compare_excel_files(self):
        """对比两个Excel文件"""
        if not self.file_path_1 or not self.file_path_2:
            self.result_label.setText("请先选择两个Excel文件")
            self.log("请先选择两个Excel文件")
            logger().info("请先选择两个Excel文件")
            return

        column_name = self.column_name_input.text().strip()
        if not column_name:
            self.result_label.setText("请输入要比较的列名")
            self.log("请输入要比较的列名")
            logger().info("请输入要比较的列名")
            return

        try:
            # 读取Excel文件
            df1 = pd.read_excel(self.file_path_1)
            df2 = pd.read_excel(self.file_path_2)

            # 检查输入的列名是否存在于两个文件中
            if column_name not in df1.columns or column_name not in df2.columns:
                self.result_label.setText(f"两个文件中必须包含名为'{column_name}'的列")
                self.log(f"两个文件中必须包含名为'{column_name}'的列")
                logger().info(f"两个文件中必须包含名为'{column_name}'的列")
                return

            # 对比指定列的数据
            mask = df1[column_name] != df2[column_name]
            differences_df1 = df1[mask]
            differences_df2 = df2[mask]

            # 合并两个DataFrame，展平MultiIndex列
            differences = pd.concat([differences_df1, differences_df2], axis=1)
            differences.columns = [f"{level1}_{level2}" if isinstance(level2, str) and level2 else level1 for level1, level2 in differences.columns]

            # 如果有差异，显示差异结果
            if not differences.empty:
                save_path = self.save_differences_to_excel(differences)
                self.result_label.setText(f"发现差异，结果已保存到(程序目录result文件夹下): <a href='file://{save_path}'>对比结果.xlsx</a>")
                self.display_differences(differences)
                self.log(f"发现差异并已保存到新的Excel文件: {save_path}")
                logger().info(f"发现差异并已保存到新的Excel文件: {save_path}")
            else:
                self.result_label.setText(f"两个文件的'{column_name}'列数据完全一致")
                self.log(f"两个文件的'{column_name}'列数据完全一致")
                logger().info(f"两个文件的'{column_name}'列数据完全一致")

        except Exception as e:
            self.result_label.setText(f"发生错误: {str(e)}")
            self.log(f"发生错误: {str(e)}")
            logger().error(f"发生错误: {str(e)}")

    def display_differences(self, differences):
        """显示差异结果"""
        # 设置表格的行和列
        self.result_table.setRowCount(differences.shape[0])
        self.result_table.setColumnCount(differences.shape[1])

        # 设置表头
        self.result_table.setHorizontalHeaderLabels(differences.columns)

        # 填充表格内容
        for row in range(differences.shape[0]):
            for col in range(differences.shape[1]):
                item = QTableWidgetItem(str(differences.iat[row, col]))
                self.result_table.setItem(row, col, item)

        # 调整列宽以适应内容
        self.result_table.resizeColumnsToContents()

    def save_differences_to_excel(self, differences):
        # 创建保存路径, 并确保目录存在
        if not os.path.exists(os.path.join(os.path.expanduser("./"), "result")):
            os.makedirs(os.path.join(os.path.expanduser("./"), "result"))

        current_path = os.path.join(os.path.expanduser("./"), "result")  # 当前路径

        save_path = os.path.join(current_path, "对比结果.xlsx")  # 保存路径

        differences.to_excel(save_path, index=False)  # 保存到Excel文件

        self.differences_file_path = save_path  # 记录保存路径

        return save_path  # 返回保存路径

    def open_file_on_link(self, link):
        # 添加调试信息
        self.log(f"点击的链接: {link}")
        QDesktopServices.openUrl(QUrl(link))

    def log(self, message):
        self.log_text_edit.appendPlainText(message)


# 如果单独运行该文件，用于测试
if __name__ == '__main__':
    app = QApplication([])
    log_text_edit = QPlainTextEdit()
    log_text_edit.setReadOnly(True)
    excel_page = ExcelPage(log_text_edit)

    log_text_edit.setWindowTitle("日志")
    log_text_edit.show()
    excel_page.setWindowTitle("Excel文件对比工具")
    excel_page.show()
    app.exec()
